package Zhan;

import List.SinNode;

public class LinkStack implements IStack {
    // 指向栈顶元素的指针
    public SinNode top;
    // 栈元素个数
    public int length;

    // 构造函数，初始化链栈为空，长度为 0
    public LinkStack() {
        this.top = null; // 初始时，栈顶指针指向 null，表示链栈为空
        this.length = 0;
    }

    // 输出栈中的所有数据元素
    public void display() {
        System.out.print("[");
        SinNode temp = top;
        // 使用临时指针 temp 从栈顶开始遍历
        while (temp != null) {
            // 获取当前节点的数据
            Object data = temp.getData();
            System.out.print(data + " ");
            // 移动到下一个节点
            temp = temp.getNext();
        }
        System.out.println("]");
    }

    // 判断栈是否为空
    public boolean isEmpty() {
        return this.length == 0;
    }

    // 返回栈中数据元素个数
    public int length() {
        return this.length;
    }

    // 返回栈顶元素，如果栈为空则抛出异常
    public Object peek() throws StackEmptyException {
        if (this.isEmpty()) {
            throw new StackEmptyException("错误，栈为空");
        }
        return top.getData();
    }

    // 入栈操作
    public void push(Object x) throws Exception {
        // 创建新节点，数据为 x，next 指向当前栈顶
        SinNode s = new SinNode(x, top);
        // 更新栈顶指针为新节点
        top = s;
        // 栈元素个数加一
        this.length++;
    }

    // 出栈操作，如果栈为空则抛出异常
    public Object pop() {
        if (this.isEmpty()) {
            throw new StackEmptyException("错误，栈为空");
        }
        // 获取栈顶元素的数据
        Object obj = top.getData();
        //将当前栈顶元素，暂时存到变量a中，方便后面与当前栈断开连接
        SinNode a = top;
        // 更新栈顶指针为下一个节点
        top = top.getNext();
        // 断开原栈顶与新栈顶的连接，防止内存泄漏
        a.setNext(null);
        // 栈元素个数减一
        this.length--;
        return obj;
    }
}